home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / comm2 / termsorc.lha / Extras / Source / term-source.lha / termEmulation.c < prev    next >
C/C++ Source or Header  |  1995-09-26  |  52KB  |  3,277 lines

  1. /*
  2. **    termEmulation.c
  3. **
  4. **    Terminal emulation (parsing and processing) routines
  5. **
  6. **    Copyright © 1990-1995 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* How many characters we will keep in the scan buffer. */
  13.  
  14. #define MAX_SCAN_SIZE    256
  15.  
  16.     /* Flag indicating whether the cursor has already been
  17.      * erased or not.
  18.      */
  19.  
  20. STATIC BYTE        CursorEnabled    = FALSE,
  21.             CursorInvisible    = FALSE;
  22.  
  23.     /* Cursor handling data. */
  24.  
  25. STATIC WORD        LastCursorX = -1,
  26.             LastCursorY = -1;
  27.  
  28. STATIC LONG        DestX,
  29.             DestY,
  30.             XSize,
  31.             FontByColumn;
  32.  
  33. STATIC BYTE        CursorGhosted = FALSE;
  34.  
  35.     /* Backup style. */
  36.  
  37. STATIC UBYTE        StyleType = FS_NORMAL;
  38.  
  39.     /* Cursor backup data. */
  40.  
  41. STATIC struct CursorData    CursorBackup;
  42. STATIC BYTE            CursorBackupValid;
  43.  
  44.     /* A couple of internally referenced variables. */
  45.  
  46. STATIC BYTE        CharsInBuffer    = 0,
  47.             ScanStep    = 0;
  48. STATIC UBYTE __far    SaveBuffer[MAX_SCAN_SIZE + 1];
  49. STATIC STRPTR        Arnie        = NULL;
  50.  
  51. STATIC BYTE        PrintFormFeed    = FALSE,
  52.             PrintFullScreen    = FALSE;
  53.  
  54.     /* UpdatePens(VOID):
  55.      *
  56.      *    Update colour and style.
  57.      */
  58.  
  59. VOID
  60. UpdatePens()
  61. {
  62.     UWORD    ForePen,
  63.         BackPen,
  64.         Attrs,
  65.         TextFlags = 0,
  66.         Mask;
  67.  
  68.         // Update the colour mask.
  69.  
  70.     switch(Config -> ScreenConfig -> ColourMode)
  71.     {
  72.         case COLOUR_AMIGA:
  73.  
  74.             Mask = MIN(DepthMask,3);
  75.  
  76.             break;
  77.  
  78.         case COLOUR_EIGHT:
  79.  
  80.             Mask = MIN(DepthMask,7);
  81.  
  82.             break;
  83.  
  84.         case COLOUR_SIXTEEN:
  85.  
  86.             Mask = MIN(DepthMask,15);
  87.  
  88.             break;
  89.  
  90.         case COLOUR_MONO:
  91.  
  92.             Mask = MIN(DepthMask,1);
  93.  
  94.             break;
  95.     }
  96.  
  97.         // Convert the colours and the text attributes
  98.  
  99.     ForePen    = PenTable[ForegroundPen];
  100.     BackPen    = PenTable[BackgroundPen];
  101.     Attrs    = TextAttributeTable[Attributes];
  102.  
  103.         // Choose a sensible colour
  104.  
  105.     if(ForePen > Mask)
  106.     {
  107.         if(BackPen > Mask)
  108.         {
  109.             if(BackPen <= ForePen)
  110.             {
  111.                 ForePen = GetPenIndex(SafeTextPen);
  112.                 BackPen = 0;
  113.             }
  114.             else
  115.             {
  116.                 ForePen = 0;
  117.                 BackPen = GetPenIndex(SafeTextPen);
  118.             }
  119.         }
  120.         else
  121.         {
  122.             if(GetPenIndex(SafeTextPen) == BackPen)
  123.                 ForePen = 0;
  124.             else
  125.                 ForePen = GetPenIndex(SafeTextPen);
  126.         }
  127.     }
  128.     else
  129.     {
  130.         if(BackPen > Mask)
  131.         {
  132.             if(!ForePen)
  133.                 BackPen = GetPenIndex(SafeTextPen);
  134.             else
  135.                 BackPen = 0;
  136.         }
  137.     }
  138.  
  139.         // Take care of the text attributes
  140.  
  141.     if(Attrs & ATTR_UNDERLINE)
  142.         TextFlags |= FSF_UNDERLINED;
  143.  
  144.     if(Attributes & ATTR_HIGHLIGHT)
  145.     {
  146.         if(Config -> ScreenConfig -> ColourMode == COLOUR_SIXTEEN)
  147.             ForePen |= 8;
  148.         else
  149.             TextFlags |= FSF_BOLD;
  150.     }
  151.  
  152.     if((Attributes & ATTR_BLINK) && (Config -> TerminalConfig -> EmulationMode == EMULATION_ANSIVT100))
  153.     {
  154.         switch(Config -> ScreenConfig -> ColourMode)
  155.         {
  156.             case COLOUR_AMIGA:
  157.  
  158.                 ForePen = 3;
  159.  
  160.                 break;
  161.  
  162.             case COLOUR_EIGHT:
  163.  
  164.                 ForePen |= 8;
  165.  
  166.                 break;
  167.  
  168.             case COLOUR_SIXTEEN:
  169.  
  170.                 if(Screen && DepthMask > 15)
  171.                     ForePen |= 16;
  172.  
  173.                 break;
  174.  
  175.             case COLOUR_MONO:
  176.  
  177.                 ForePen = GetPenIndex(SafeTextPen);
  178.  
  179.                 break;
  180.         }
  181.     }
  182.  
  183.         // Make sure that monochrome text renders properly
  184.  
  185.     if(Config -> ScreenConfig -> ColourMode == COLOUR_MONO)
  186.     {
  187.             // Out of bounds?
  188.  
  189.         if(ForePen > 1)
  190.         {
  191.                 // If it's #7 then it's white, else it's black
  192.  
  193.             if(ForePen == 7)
  194.                 ForePen = GetPenIndex(SafeTextPen);
  195.             else
  196.                 ForePen = 0;
  197.         }
  198.  
  199.         if(BackPen > 1)
  200.         {
  201.             if(BackPen == 7)
  202.                 BackPen = GetPenIndex(SafeTextPen);
  203.             else
  204.                 BackPen = 0;
  205.         }
  206.  
  207.             // Oops... the text should be readable
  208.  
  209.         if(ForePen == BackPen)
  210.         {
  211.                 // Inverse video?
  212.  
  213.             if(BackPen)
  214.             {
  215.                 ForePen = 0;
  216.                 BackPen = GetPenIndex(SafeTextPen);
  217.             }
  218.             else
  219.             {
  220.                 ForePen = GetPenIndex(SafeTextPen);
  221.                 BackPen = 0;
  222.             }
  223.         }
  224.     }
  225.  
  226.     if(Attrs & ATTR_INVERSE)
  227.     {
  228.         UWORD Help;
  229.  
  230.         Help    = ForePen;
  231.         ForePen    = BackPen;
  232.         BackPen    = Help;
  233.     }
  234.  
  235.     if(TextFlags != StyleType)
  236.     {
  237.         SetSoftStyle(RPort,TextFlags,0xFF);
  238.  
  239.         StyleType = TextFlags;
  240.     }
  241.  
  242.     FgPen = MappedPens[0][ForePen];
  243.     BgPen = MappedPens[0][BackPen];
  244.  
  245.     if(FgPen != ReadAPen(RPort))
  246.         SetAPen(RPort,FgPen);
  247.  
  248.     if(BgPen != ReadBPen(RPort))
  249.         SetBPen(RPort,BgPen);
  250. }
  251.  
  252.     /* GetFontWidth():
  253.      *
  254.      *    Get the font width of the current line.
  255.      */
  256.  
  257. WORD
  258. GetFontWidth()
  259. {
  260.     if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  261.     {
  262.         if(CurrentCharWidth == SCALE_HALF)
  263.             return((WORD)(TextFontWidth / 2));
  264.         else
  265.             return(TextFontWidth);
  266.     }
  267.     else
  268.     {
  269.         if(CurrentCharWidth == SCALE_HALF)
  270.             return(TextFontWidth);
  271.         else
  272.             return((WORD)(TextFontWidth * 2));
  273.     }
  274. }
  275.  
  276.     /* RethinkRasterLimit():
  277.      *
  278.      *    Take care of the extreme left column position
  279.      *    permitted.
  280.      */
  281.  
  282. VOID
  283. RethinkRasterLimit()
  284. {
  285.     register LONG Y;
  286.  
  287.     if(CursorY > LastLine)
  288.         Y = LastLine;
  289.     else
  290.     {
  291.         if(CursorY < 0)
  292.             Y = 0;
  293.         else
  294.             Y = CursorY;
  295.     }
  296.  
  297.     if(RasterAttr[Y] == SCALE_ATTR_NORMAL)
  298.     {
  299.         if(CurrentCharWidth == SCALE_HALF)
  300.             FontByColumn = (LastColumn + 1) * 2 - 1;
  301.         else
  302.             FontByColumn = LastColumn;
  303.     }
  304.     else
  305.     {
  306.         if(CurrentCharWidth == SCALE_HALF)
  307.             FontByColumn = LastColumn;
  308.         else
  309.             FontByColumn = ((LastColumn + 1) / 2) - 1;
  310.     }
  311. }
  312.  
  313.     /* ScrollRegion(WORD Direction):
  314.      *
  315.      *    Scroll the current scroll region up or down.
  316.      */
  317.  
  318. VOID __regargs
  319. ScrollRegion(WORD Direction)
  320. {
  321.     WORD RegionTop,RegionBottom,RegionLines;
  322.     LONG Dir,MinY,MaxY;
  323.  
  324.     if(Direction < 0)
  325.         Dir = -Direction;
  326.     else
  327.         Dir = Direction;
  328.  
  329.     if(RegionSet)
  330.     {
  331.         MinY         = MUL_Y(Top);
  332.         MaxY        = MUL_Y(Bottom + 1) - 1;
  333.  
  334.         RegionTop    = Top;
  335.         RegionBottom    = Bottom + 1;
  336.         RegionLines    = Bottom - Top + 1;
  337.     }
  338.     else
  339.     {
  340.         MinY        = 0;
  341.         MaxY         = MUL_Y(LastLine + 1) - 1;
  342.  
  343.         RegionTop    = 0;
  344.         RegionBottom    = LastLine + 1;
  345.         RegionLines    = LastLine + 1;
  346.     }
  347.  
  348.     BackupRender();
  349.  
  350.     RasterScrollRegion(Direction,RegionTop,RegionBottom,RegionLines);
  351.  
  352.     if(Config -> EmulationConfig -> ScrollMode == SCROLL_JUMP)
  353.     {
  354.         if(Dir > RegionLines)
  355.             ScrollLineRectFill(RPort,0,MinY,LastPixel,MaxY);
  356.         else
  357.         {
  358.             if(Direction > 0)
  359.                 ScrollLineRaster(RPort,0,MUL_Y(Direction),0,MinY,LastPixel,MaxY,FALSE);
  360.             else
  361.                 ScrollLineRaster(RPort,0,-MUL_Y(-Direction),0,MinY,LastPixel,MaxY,FALSE);
  362.         }
  363.     }
  364.     else
  365.     {
  366.         if(Dir > RegionLines)
  367.         {
  368.             if(Direction > 0)
  369.                 Direction = RegionLines;
  370.             else
  371.                 Direction = -RegionLines;
  372.         }
  373.  
  374.         if(Direction > 0)
  375.             ScrollLineRaster(RPort,0,MUL_Y(Direction),0,MinY,LastPixel,MaxY,TRUE);
  376.         else
  377.             ScrollLineRaster(RPort,0,-MUL_Y(-Direction),0,MinY,LastPixel,MaxY,TRUE);
  378.     }
  379.  
  380.     BackupRender();
  381. }
  382.  
  383.     /* LastChar(STRPTR Buffer):
  384.      *
  385.      *    Return the last character in a string.
  386.      */
  387.  
  388. STATIC UBYTE __inline
  389. LastChar(STRPTR Buffer)
  390. {
  391.     WORD Offset = 0;
  392.  
  393.     while(Buffer[Offset])
  394.         Offset++;
  395.  
  396.     return(Buffer[Offset - 1]);
  397. }
  398.  
  399.     /* ReadValue(STRPTR Buffer,BYTE *Value):
  400.      *
  401.      *    Parse a buffer for numbers and return a pointer
  402.      *    to the next buffer element to contain additional
  403.      *    information.
  404.      */
  405.  
  406. STATIC STRPTR __inline
  407. ReadValue(STRPTR Buffer,WORD *Value)
  408. {
  409.     while(*Buffer && *Buffer != ';' && (*Buffer < '0' || *Buffer > '9'))
  410.         Buffer++;
  411.  
  412.     if(*Buffer)
  413.     {
  414.         *Value = 0;
  415.  
  416.         while(*Buffer >= '0' && *Buffer <= '9')
  417.             *Value = (*Value * 10) + (*Buffer++ - '0');
  418.     }
  419.     else
  420.         *Value = -1;
  421.  
  422.     if(*Buffer == ';' || *Buffer == ' ')
  423.         return(Buffer + 1);
  424.     else
  425.         return(NULL);
  426. }
  427.  
  428.     /* EmulationSerWrite(STRPTR String,LONG Length):
  429.      *
  430.      *    Write text to the serial line.
  431.      */
  432.  
  433. STATIC VOID __regargs
  434. EmulationSerWrite(STRPTR String,LONG Length)
  435. {
  436.     if(SysBase -> ThisTask == SpecialQueue -> SigTask)
  437.         SerWrite(String,Length);
  438.     else
  439.     {
  440.         struct DataMsg *Msg;
  441.  
  442.         if(Length == -1)
  443.             Length = strlen(String);
  444.  
  445.         if(Msg = (struct DataMsg *)CreateMsgItem(sizeof(struct DataMsg) + Length + 1))
  446.         {
  447.             Msg -> Type = DATAMSGTYPE_WRITE;
  448.             Msg -> Data = (STRPTR)(Msg + 1);
  449.             Msg -> Size = Length;
  450.  
  451.             CopyMem(String,Msg -> Data,Length + 1);
  452.  
  453.             PutMsgItem(SpecialQueue,(struct MsgItem *)Msg);
  454.         }
  455.     }
  456. }
  457.  
  458.     /* RethinkCursorPosition():
  459.      *
  460.      *    Calculate the new cursor position.
  461.      */
  462.  
  463. STATIC VOID
  464. RethinkCursorPosition(VOID)
  465. {
  466.     if(CursorY != LastCursorY || CursorX != LastCursorX)
  467.     {
  468.         STATIC LONG X,Y;
  469.  
  470.         if(CursorY != LastCursorY)
  471.         {
  472.             if(CursorY > LastLine)
  473.                 Y = LastLine;
  474.             else
  475.             {
  476.                 if(CursorY < 0)
  477.                     Y = 0;
  478.                 else
  479.                     Y = CursorY;
  480.             }
  481.  
  482.             if(RasterAttr[Y] == SCALE_ATTR_NORMAL)
  483.             {
  484.                 if(CurrentCharWidth == SCALE_HALF)
  485.                     FontByColumn = ((LastColumn + 1) * 2) - 1;
  486.                 else
  487.                     FontByColumn = LastColumn;
  488.             }
  489.             else
  490.             {
  491.                 if(CurrentCharWidth == SCALE_HALF)
  492.                     FontByColumn = LastColumn;
  493.                 else
  494.                     FontByColumn = ((LastColumn + 1) / 2) - 1;
  495.             }
  496.  
  497.             DestY = MUL_Y(Y);
  498.  
  499.             LastCursorY = CursorY;
  500.         }
  501.  
  502.         LastCursorX = CursorX;
  503.  
  504.         if(CursorX > FontByColumn)
  505.             X = FontByColumn;
  506.         else
  507.         {
  508.             if(CursorX < 0)
  509.                 X = 0;
  510.             else
  511.                 X = CursorX;
  512.         }
  513.  
  514.         if(CurrentCharWidth == SCALE_NORMAL)
  515.         {
  516.             if(RasterAttr[Y] == SCALE_ATTR_NORMAL)
  517.             {
  518.                     // Normal width
  519.  
  520.                 DestX = MUL_X(X);
  521.                 XSize = TextFontWidth;
  522.             }
  523.             else
  524.             {
  525.                     // Double width
  526.  
  527.                 DestX = MUL_X(X) * 2;
  528.                 XSize = TextFontWidth * 2;
  529.             }
  530.         }
  531.         else
  532.         {
  533.             if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  534.             {
  535.                     // Half width
  536.  
  537.                 DestX = MUL_X(X) / 2;
  538.                 XSize = TextFontWidth / 2;
  539.             }
  540.             else
  541.             {
  542.                     // Twice the half width
  543.  
  544.                 DestX = MUL_X(X);
  545.                 XSize = TextFontWidth;
  546.             }
  547.         }
  548.     }
  549. }
  550.  
  551.     /* ToggleCursor():
  552.      *
  553.      *    (Re)draw the cursor image.
  554.      */
  555.  
  556. STATIC VOID
  557. ToggleCursor(VOID)
  558. {
  559.     if(Config -> TerminalConfig -> EmulationMode != EMULATION_EXTERNAL)
  560.     {
  561.         UWORD    OldAPen    = ReadAPen(RPort),
  562.             OldBPen    = ReadBPen(RPort),
  563.             OldDrMd    = ReadDrMd(RPort),
  564.  
  565.             Left    = WindowLeft + DestX,
  566.             Top    = WindowTop + DestY;
  567.  
  568.         if(Kick30)
  569.         {
  570.             SetABPenDrMd(RPort,DepthMask,OldBPen,JAM1 | COMPLEMENT);
  571.  
  572.             if(UseMasking)
  573.             {
  574.                 UBYTE Mask = RPort -> Mask;
  575.  
  576.                 SetMask(RPort,DepthMask);
  577.  
  578.                 RectFill(RPort,Left,Top,Left + XSize - 1,Top + TextFontHeight - 1);
  579.  
  580.                 SetMask(RPort,Mask);
  581.             }
  582.             else
  583.                 RectFill(RPort,Left,Top,Left + XSize - 1,Top + TextFontHeight - 1);
  584.  
  585.             SetABPenDrMd(RPort,OldAPen,OldBPen,OldDrMd);
  586.         }
  587.         else
  588.         {
  589.             SetAPen(RPort,DepthMask);
  590.             SetDrMd(RPort,JAM1 | COMPLEMENT);
  591.  
  592.             if(UseMasking)
  593.             {
  594.                 UBYTE Mask = RPort -> Mask;
  595.  
  596.                 SetMask(RPort,DepthMask);
  597.  
  598.                 RectFill(RPort,Left,Top,Left + XSize - 1,Top + TextFontHeight - 1);
  599.  
  600.                 SetMask(RPort,Mask);
  601.             }
  602.             else
  603.                 RectFill(RPort,Left,Top,Left + XSize - 1,Top + TextFontHeight - 1);
  604.  
  605.             SetAPen(RPort,OldAPen);
  606.             SetDrMd(RPort,OldDrMd);
  607.         }
  608.     }
  609. }
  610.  
  611.     /* RedrawCursor():
  612.      *
  613.      *    Change the appearance of the cursor.
  614.      */
  615.  
  616. STATIC VOID
  617. RedrawCursor(VOID)
  618. {
  619.     ObtainSemaphore(&TerminalSemaphore);
  620.  
  621.     RethinkCursorPosition();
  622.  
  623.     if(CursorGhosted)
  624.     {
  625.         SetAfPt(RPort,(UWORD *)&Crosshatch,1);
  626.  
  627.         ToggleCursor();
  628.  
  629.         SetAfPt(RPort,NULL,0);
  630.     }
  631.     else
  632.         ToggleCursor();
  633.  
  634.     ReleaseSemaphore(&TerminalSemaphore);
  635. }
  636.  
  637.     /* DoCancel():
  638.      *
  639.      *    Cancel any currently scanned sequence.
  640.      */
  641.  
  642. BYTE
  643. DoCancel()
  644. {
  645.     InSequence    = FALSE;
  646.     CharsInBuffer    = ScanStep = 0;
  647.  
  648.     return(FALSE);
  649. }
  650.  
  651.     /* CSIFake():
  652.      *
  653.      *    This routine was added to support 8-bit control
  654.      *    sequences introduced by a CSI character.
  655.      */
  656.  
  657. VOID
  658. CSIFake()
  659. {
  660.         /* Reset scanner */
  661.  
  662.     DoCancel();
  663.  
  664.         /* Perform as if ESC [ had been transmitted. */
  665.  
  666.     InSequence = ParseCode('[');
  667. }
  668.  
  669.     /* ParseCode(UBYTE c):
  670.      *
  671.      *    Input:    A character to be passed through the ANSI code
  672.      *        parser.
  673.      *
  674.      *    Output:    FALSE if input characters did form a valid ANSI
  675.      *        control sequence or if input characters did not
  676.      *        form an ANSI control sequence at all.
  677.      *
  678.      *        TRUE if input characters did possibly introduce
  679.      *        a valid ANSI control sequence.
  680.      */
  681.  
  682. BYTE
  683. ParseCode(UBYTE c)
  684. {
  685.         /* ScanStep = 0:    This is the first character
  686.          *            to introduce a control sequence.
  687.          */
  688.  
  689.     if(!ScanStep)
  690.     {
  691.         register WORD i;
  692.  
  693.             /* Scan all available codes and try to find
  694.              * a match.
  695.              */
  696.  
  697.         for(i = 0 ; i < NumCodes ; i++)
  698.         {
  699.                 /* This character may introduce a
  700.                  * control sequence.
  701.                  */
  702.  
  703.             if(ANSICode[i] . FirstChar == c)
  704.             {
  705.                     /* If this is a single
  706.                      * character control sequence
  707.                      * call the appropriate function
  708.                      * and exit immediately.
  709.                      */
  710.  
  711.                 if(ANSICode[i] . ExactSize == 1)
  712.                 {
  713.                     if(Config -> TerminalConfig -> EmulationMode != EMULATION_ATOMIC)
  714.                     {
  715.                         SaveBuffer[CharsInBuffer++] = c;
  716.                         SaveBuffer[CharsInBuffer  ] = 0;
  717.  
  718.                         (*ANSICode[i] . Func)(SaveBuffer);
  719.                     }
  720.  
  721.                     CharsInBuffer = ScanStep = 0;
  722.  
  723.                     return(FALSE);
  724.                 }
  725.                 else
  726.                 {
  727.                         /* The length of this control
  728.                          * sequence is greater than
  729.                          * a single character. Save
  730.                          * the input character and
  731.                          * return.
  732.                          */
  733.  
  734.                     ScanStep = i;
  735.  
  736.                     SaveBuffer[CharsInBuffer++] = c;
  737.  
  738.                         /* Where to stop. */
  739.  
  740.                     Arnie = ANSICode[i] . Terminator;
  741.  
  742.                     return(TRUE);
  743.                 }
  744.             }
  745.         }
  746.     }
  747.     else
  748.     {
  749.         if(CharsInBuffer < MAX_SCAN_SIZE)
  750.         {
  751.             if(Arnie)
  752.             {
  753.                 register WORD i;
  754.  
  755.                     /* Scan the remaining codes for a match. */
  756.  
  757.                 for(i = ScanStep ; i < NumCodes ; i++)
  758.                 {
  759.                         /* This sequence begins with the
  760.                          * same character the parser was
  761.                          * initialized with, so let's take
  762.                          * a look at it.
  763.                          */
  764.  
  765.                     if(ANSICode[i] . FirstChar == SaveBuffer[0])
  766.                     {
  767.                             /* This character is supposed to
  768.                              * terminate the sequence, so exit.
  769.                              */
  770.  
  771.                         if(Arnie[c])
  772.                         {
  773.                             if(Config -> TerminalConfig -> EmulationMode != EMULATION_ATOMIC)
  774.                             {
  775.                                 SaveBuffer[CharsInBuffer++] = c;
  776.                                 SaveBuffer[CharsInBuffer  ] = 0;
  777.  
  778.                                 (*ANSICode[i] . Func)(SaveBuffer);
  779.                             }
  780.  
  781.                             CharsInBuffer = ScanStep = 0;
  782.  
  783.                             Arnie = NULL;
  784.  
  785.                             return(FALSE);
  786.                         }
  787.                         else
  788.                         {
  789.                                 /* If this character is part of
  790.                                  * a legal sequence store it
  791.                                  * and return.
  792.                                  */
  793.  
  794.                             if(ANSICode[i] . Match[c])
  795.                             {
  796.                                 ScanStep = i;
  797.  
  798.                                 SaveBuffer[CharsInBuffer++] = c;
  799.  
  800.                                 return(TRUE);
  801.                             }
  802.                         }
  803.                     }
  804.                 }
  805.             }
  806.             else
  807.             {
  808.                 register WORD i;
  809.  
  810.                 for(i = ScanStep ; i < NumCodes ; i++)
  811.                 {
  812.                         /* This sequence begins with the
  813.                          * same character the parser was
  814.                          * initialized with, so let's take
  815.                          * a look at it.
  816.                          */
  817.  
  818.                     if(ANSICode[i] . FirstChar == SaveBuffer[0])
  819.                     {
  820.                             /* This character is supposed to
  821.                              * terminate the sequence, so exit.
  822.                              */
  823.  
  824.                         if(ANSICode[i] . LastChar == c || (!ANSICode[i] . LastChar && CharsInBuffer == 2 && ANSICode[i] . ExactSize == 3))    // Special case for VT52
  825.                         {
  826.                             if(Config -> TerminalConfig -> EmulationMode != EMULATION_ATOMIC)
  827.                             {
  828.                                 SaveBuffer[CharsInBuffer++] = c;
  829.                                 SaveBuffer[CharsInBuffer  ] = 0;
  830.  
  831.                                 (*ANSICode[i] . Func)(SaveBuffer);
  832.                             }
  833.  
  834.                             CharsInBuffer = ScanStep = 0;
  835.  
  836.                             return(FALSE);
  837.                         }
  838.                         else
  839.                         {
  840.                                 /* If this character is part of
  841.                                  * a legal sequence store it
  842.                                  * and return.
  843.                                  */
  844.  
  845.                             if(ANSICode[i] . Match[c])
  846.                             {
  847.                                 ScanStep = i;
  848.  
  849.                                 SaveBuffer[CharsInBuffer++] = c;
  850.  
  851.                                 return(TRUE);
  852.                             }
  853.                         }
  854.                     }
  855.                 }
  856.             }
  857.         }
  858.     }
  859.  
  860.         /* Return failure. */
  861.  
  862.     CharsInBuffer = ScanStep = 0;
  863.  
  864.     Arnie = NULL;
  865.  
  866.     return(FALSE);
  867. }
  868.  
  869.     /* NormalCursor():
  870.      *
  871.      *    Enable normal (filled) cursor image.
  872.      */
  873.  
  874. VOID
  875. NormalCursor()
  876. {
  877.     ObtainSemaphore(&TerminalSemaphore);
  878.  
  879.     if(CursorGhosted)
  880.     {
  881.         if(CursorEnabled && !CursorInvisible)
  882.         {
  883.             SetAfPt(RPort,(UWORD *)&Crosshatch,1);
  884.  
  885.             ToggleCursor();
  886.  
  887.             SetAfPt(RPort,NULL,0);
  888.  
  889.             ToggleCursor();
  890.         }
  891.  
  892.         CursorGhosted = FALSE;
  893.     }
  894.  
  895.     ReleaseSemaphore(&TerminalSemaphore);
  896. }
  897.  
  898.     /* GhostCursor():
  899.      *
  900.      *    Enable ghosted (checkered) cursor image.
  901.      */
  902.  
  903. VOID
  904. GhostCursor()
  905. {
  906.     ObtainSemaphore(&TerminalSemaphore);
  907.  
  908.     if(!CursorGhosted)
  909.     {
  910.         if(CursorEnabled && !CursorInvisible)
  911.         {
  912.             ToggleCursor();
  913.  
  914.             SetAfPt(RPort,(UWORD *)&Crosshatch,1);
  915.  
  916.             ToggleCursor();
  917.  
  918.             SetAfPt(RPort,NULL,0);
  919.         }
  920.  
  921.         CursorGhosted = TRUE;
  922.     }
  923.  
  924.     ReleaseSemaphore(&TerminalSemaphore);
  925. }
  926.  
  927.     /* RepositionCursor():
  928.      *
  929.      *    Redraw the cursor at the new position.
  930.      */
  931.  
  932. VOID
  933. RepositionCursor()
  934. {
  935.     ObtainSemaphore(&TerminalSemaphore);
  936.  
  937.     RethinkCursorPosition();
  938.  
  939.     Move(RPort,WindowLeft + DestX,WindowTop + DestY + TextFontBase);
  940.  
  941.     ReleaseSemaphore(&TerminalSemaphore);
  942. }
  943.  
  944.     /* ClearCursor():
  945.      *
  946.      *    Clear the cursor image.
  947.      */
  948.  
  949. VOID
  950. ClearCursor()
  951. {
  952.     ObtainSemaphore(&TerminalSemaphore);
  953.  
  954.     if(CursorEnabled && !CursorInvisible)
  955.     {
  956.         RedrawCursor();
  957.  
  958.         CursorEnabled = FALSE;
  959.     }
  960.  
  961.     ReleaseSemaphore(&TerminalSemaphore);
  962. }
  963.  
  964.     /* DrawCursor():
  965.      *
  966.      *    Explicitely (re-)draw the cursor image.
  967.      */
  968.  
  969. VOID
  970. DrawCursor()
  971. {
  972.     ObtainSemaphore(&TerminalSemaphore);
  973.  
  974.     if(!CursorEnabled && !CursorInvisible)
  975.     {
  976.         RedrawCursor();
  977.  
  978.         CursorEnabled = TRUE;
  979.     }
  980.  
  981.     ReleaseSemaphore(&TerminalSemaphore);
  982. }
  983.  
  984.     /* BackupRender():
  985.      *
  986.      *    Save current draw modes, pen and position or restore
  987.      *    the data.
  988.      */
  989.  
  990. VOID
  991. BackupRender()
  992. {
  993.     STATIC BYTE    Called = FALSE;
  994.     STATIC UBYTE    DrMd,
  995.             FgPen,
  996.             BgPen;
  997.     STATIC UWORD    OldX,OldY;
  998.     STATIC UBYTE    Style;
  999.  
  1000.     if(!Called)
  1001.     {
  1002.         DrMd    = ReadDrMd(RPort);
  1003.         FgPen    = ReadAPen(RPort);
  1004.         BgPen    = ReadBPen(RPort);
  1005.  
  1006.         OldX    = RPort -> cp_x - WindowLeft;
  1007.         OldY    = RPort -> cp_y - WindowTop;
  1008.  
  1009.         Style    = StyleType;
  1010.  
  1011.         Called    = TRUE;
  1012.     }
  1013.     else
  1014.     {
  1015.         if(ReadDrMd(RPort) != DrMd)
  1016.             SetDrMd(RPort,DrMd);
  1017.  
  1018.         if(ReadAPen(RPort) != FgPen)
  1019.             SetAPen(RPort,FgPen);
  1020.  
  1021.         if(ReadBPen(RPort) != BgPen)
  1022.             SetBPen(RPort,BgPen);
  1023.  
  1024.         Move(RPort,OldX + WindowLeft,OldY + WindowTop);
  1025.  
  1026.         if(Style != StyleType)
  1027.         {
  1028.             SetSoftStyle(RPort,Style,0xFF);
  1029.  
  1030.             StyleType = Style;
  1031.         }
  1032.  
  1033.         Called = FALSE;
  1034.     }
  1035. }
  1036.  
  1037.     /* ShiftChar(LONG Size):
  1038.      *
  1039.      *    Simulate character insertion at the current cursor
  1040.      *    position by shifting the whole line Size times eight pixels
  1041.      *    to the right.
  1042.      */
  1043.  
  1044. VOID __regargs
  1045. ShiftChar(LONG Size)
  1046. {
  1047.     LONG DeltaX,MinX,MinY;
  1048.  
  1049.     MinY = MUL_Y(CursorY);
  1050.  
  1051.     if(CurrentCharWidth == SCALE_NORMAL)
  1052.     {
  1053.         if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  1054.         {
  1055.             DeltaX    = MUL_X(Size);
  1056.             MinX    = MUL_X(CursorX);
  1057.         }
  1058.         else
  1059.         {
  1060.             DeltaX    = MUL_X(Size) * 2;
  1061.             MinX    = MUL_X(CursorX) * 2;
  1062.         }
  1063.     }
  1064.     else
  1065.     {
  1066.         if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  1067.         {
  1068.             DeltaX    = MUL_X(Size) / 2;
  1069.             MinX    = MUL_X(CursorX) / 2;
  1070.         }
  1071.         else
  1072.         {
  1073.             DeltaX    = MUL_X(Size);
  1074.             MinX    = MUL_X(CursorX);
  1075.         }
  1076.     }
  1077.  
  1078.     if(MinX < WindowWidth)
  1079.     {
  1080.         BackupRender();
  1081.  
  1082.         ScrollLineRasterNoTabChange(RPort,-DeltaX,0,MinX,MinY,LastPixel,MinY + TextFontHeight - 1,FALSE);
  1083.  
  1084.         BackupRender();
  1085.     }
  1086. }
  1087.  
  1088.     /* Ignore():
  1089.      *
  1090.      *    Do nothing, return immediately.
  1091.      */
  1092.  
  1093. VOID
  1094. Ignore()
  1095. {
  1096. }
  1097.  
  1098.     /* ScrollDown(STRPTR Buffer):
  1099.      *
  1100.      *    Scroll the current region down.
  1101.      */
  1102.  
  1103. VOID
  1104. ScrollDown(STRPTR Buffer)
  1105. {
  1106.     WORD Value;
  1107.  
  1108.     ReadValue(Buffer,&Value);
  1109.  
  1110.     if(Value < 1)
  1111.         Value = 1;
  1112.  
  1113.     ScrollRegion(-Value);
  1114. }
  1115.  
  1116.     /* ScrollUp(STRPTR Buffer):
  1117.      *
  1118.      *    Scroll the current region up.
  1119.      */
  1120.  
  1121. VOID
  1122. ScrollUp(STRPTR Buffer)
  1123. {
  1124.     WORD Value;
  1125.  
  1126.     ReadValue(Buffer,&Value);
  1127.  
  1128.     if(Value < 1)
  1129.         Value = 1;
  1130.  
  1131.     ScrollRegion(Value);
  1132. }
  1133.  
  1134.     /* CursorScrollDown():
  1135.      *
  1136.      *    Move cursor down and scroll region if necessary.
  1137.      */
  1138.  
  1139. VOID
  1140. CursorScrollDown()
  1141. {
  1142.     DownLine();
  1143.  
  1144.     RepositionCursor();
  1145. }
  1146.  
  1147. VOID
  1148. DownLine()
  1149. {
  1150.     UBYTE InRegion = TRUE;
  1151.     WORD  Hit      = LastLine;
  1152.  
  1153.     if(RegionSet)
  1154.     {
  1155.         if(CursorY <= Bottom)
  1156.             Hit = Bottom;
  1157.         else
  1158.             InRegion = FALSE;
  1159.     }
  1160.  
  1161.     if(CursorY == Hit)
  1162.     {
  1163.         if(InRegion)
  1164.             ScrollRegion(1);
  1165.     }
  1166.     else
  1167.     {
  1168.         CursorY++;
  1169.  
  1170.         if(CursorY > LastLine)
  1171.             CursorY = LastLine;
  1172.  
  1173.         ConFontScaleUpdate();
  1174.     }
  1175. }
  1176.  
  1177.     /* CursorScrollUp():
  1178.      *
  1179.      *    Move cursor up and scroll region if necessary.
  1180.      */
  1181.  
  1182. VOID
  1183. CursorScrollUp()
  1184. {
  1185.     BYTE InRegion    = TRUE;
  1186.     WORD Hit    = 0;
  1187.  
  1188.     if(RegionSet)
  1189.     {
  1190.         if(CursorY >= Top)
  1191.             Hit = Top;
  1192.         else
  1193.             InRegion = FALSE;
  1194.     }
  1195.  
  1196.     if(CursorY == Hit)
  1197.     {
  1198.         if(InRegion)
  1199.             ScrollRegion(-1);
  1200.     }
  1201.     else
  1202.     {
  1203.         if(--CursorY < 0)
  1204.             CursorY = 0;
  1205.  
  1206.         ConFontScaleUpdate();
  1207.     }
  1208.  
  1209.     RepositionCursor();
  1210. }
  1211.  
  1212.     /* NextLine():
  1213.      *
  1214.      *    Do something like CR+LF.
  1215.      */
  1216.  
  1217. VOID
  1218. NextLine()
  1219. {
  1220.     CursorX = 0;
  1221.  
  1222.     DownLine();
  1223.  
  1224.     RepositionCursor();
  1225. }
  1226.  
  1227.     /* SaveCursor():
  1228.      *
  1229.      *    Save cursor position and rendering attributes.
  1230.      */
  1231.  
  1232. VOID
  1233. SaveCursor()
  1234. {
  1235.     CursorBackup . Charset        = Charset;
  1236.     CursorBackup . Attributes    = Attributes;
  1237.     CursorBackup . CursorX        = CursorX;
  1238.     CursorBackup . CursorY        = CursorY;
  1239.     CursorBackup . Style        = StyleType;
  1240.     CursorBackup . FgPen        = ForegroundPen;
  1241.     CursorBackup . BgPen        = BackgroundPen;
  1242.     CursorBackup . CurrentFont    = CurrentFont;
  1243.     CursorBackup . CharMode[0]    = CharMode[0];
  1244.     CursorBackup . CharMode[1]    = CharMode[1];
  1245.  
  1246.     CursorBackupValid = TRUE;
  1247. }
  1248.  
  1249.     /* FontStuff(STRPTR Buffer):
  1250.      *
  1251.      *    Set the drawing font (standard characters/line).
  1252.      */
  1253.  
  1254. VOID
  1255. FontStuff(STRPTR Buffer)
  1256. {
  1257.     BYTE Changed = FALSE;
  1258.  
  1259.     if(Buffer[0] == '(')
  1260.     {
  1261.         switch(LastChar(Buffer))
  1262.         {
  1263.             case 'A':
  1264.             case 'B':
  1265.  
  1266.                 if(CharMode[0] != TABLE_ASCII && !Charset)
  1267.                     Changed = TRUE;
  1268.  
  1269.                 CharMode[0] = TABLE_ASCII;
  1270.  
  1271.                 break;
  1272.  
  1273.             case '0':
  1274.  
  1275.                 if(CharMode[0] != TABLE_GFX && !Charset)
  1276.                     Changed = TRUE;
  1277.  
  1278.                 CharMode[0] = TABLE_GFX;
  1279.  
  1280.                 break;
  1281.         }
  1282.     }
  1283.  
  1284.     if(Buffer[0] == ')')
  1285.     {
  1286.         switch(LastChar(Buffer))
  1287.         {
  1288.             case 'A':
  1289.             case 'B':
  1290.  
  1291.                 if(CharMode[1] != TABLE_ASCII && Charset == 1)
  1292.                     Changed = TRUE;
  1293.  
  1294.                 CharMode[1] = TABLE_ASCII;
  1295.  
  1296.                 break;
  1297.  
  1298.             case '0':
  1299.  
  1300.                 if(CharMode[1] != TABLE_GFX && Charset == 1)
  1301.                     Changed = TRUE;
  1302.  
  1303.                 CharMode[1] = TABLE_GFX;
  1304.  
  1305.                 break;
  1306.         }
  1307.     }
  1308.  
  1309.     if(Changed)
  1310.     {
  1311.         BackupRender();
  1312.  
  1313.         if(Charset)
  1314.             DoShiftIn();
  1315.         else
  1316.             DoShiftOut();
  1317.  
  1318.         BackupRender();
  1319.     }
  1320. }
  1321.  
  1322.     /* LoadCursor():
  1323.      *
  1324.      *    Load cursor position and rendering attributes.
  1325.      */
  1326.  
  1327. VOID
  1328. LoadCursor()
  1329. {
  1330.     Charset        = CursorBackup . Charset;
  1331.  
  1332.     CharMode[0]    = CursorBackup . CharMode[0];
  1333.     CharMode[1]    = CursorBackup . CharMode[1];
  1334.  
  1335.     if(CurrentFont != CursorBackup . CurrentFont)
  1336.     {
  1337.         CurrentFont = CursorBackup . CurrentFont;
  1338.  
  1339.         SetFont(RPort,CurrentFont);
  1340.  
  1341.         ConOutputUpdate();
  1342.     }
  1343.  
  1344.     ForegroundPen    = CursorBackup . FgPen;
  1345.     BackgroundPen    = CursorBackup . BgPen;
  1346.     Attributes    = CursorBackup . Attributes;
  1347.     CursorX        = CursorBackup . CursorX;
  1348.     CursorY        = CursorBackup . CursorY;
  1349.  
  1350.     UpdatePens();
  1351.  
  1352.     ConFontScaleUpdate();
  1353.  
  1354.     RepositionCursor();
  1355. }
  1356.  
  1357.     /* ScaleFont(STRPTR Buffer):
  1358.      *
  1359.      *    Select a new font scale.
  1360.      */
  1361.  
  1362. VOID
  1363. ScaleFont(STRPTR Buffer)
  1364. {
  1365.     if(!Config -> EmulationConfig -> FontLocked)
  1366.     {
  1367.         WORD NewScale,Scale;
  1368.  
  1369.         Scale = RasterAttr[CursorY];
  1370.  
  1371.         NewScale = Scale;
  1372.  
  1373.         switch(LastChar(Buffer))
  1374.         {
  1375.             case '3':
  1376.  
  1377.                 NewScale = SCALE_ATTR_TOP2X;
  1378.  
  1379.                 break;
  1380.  
  1381.             case '4':
  1382.  
  1383.                 NewScale = SCALE_ATTR_BOT2X;
  1384.  
  1385.                 break;
  1386.  
  1387.             case '5':
  1388.  
  1389.                 NewScale = SCALE_NORMAL;
  1390.  
  1391.                 break;
  1392.  
  1393.             case '6':
  1394.  
  1395.                 NewScale = SCALE_ATTR_2X;
  1396.  
  1397.                 break;
  1398.         }
  1399.  
  1400.         if(Scale != NewScale)
  1401.         {
  1402.             UBYTE    *RasterPtr    = &Raster[CursorY * RasterWidth];
  1403.             WORD     RightMargin    = LastColumn + 1,
  1404.                  CursorXSave    = CursorX;
  1405.  
  1406.             if(NewScale != SCALE_ATTR_NORMAL)
  1407.             {
  1408.                     // Twice the normal character width
  1409.  
  1410.                 if(CurrentCharWidth == SCALE_NORMAL)
  1411.                     RightMargin /= 2;
  1412.             }
  1413.             else
  1414.             {
  1415.                     // Half the normal character width
  1416.  
  1417.                 if(CurrentCharWidth != SCALE_NORMAL)
  1418.                     RightMargin *= 2;
  1419.             }
  1420.  
  1421.             RasterAttr[CursorY] = NewScale;
  1422.  
  1423.             RethinkRasterLimit();
  1424.  
  1425.             ConFontScaleUpdate();
  1426.  
  1427.             if(FontScalingRequired)
  1428.             {
  1429.                 CursorX = 0;
  1430.  
  1431.                 PrintScaled(RasterPtr,RightMargin,NewScale);
  1432.             }
  1433.             else
  1434.             {
  1435.                 Move(RPort,WindowLeft,WindowTop + MUL_Y(CursorY) + TextFontBase);
  1436.                 Text(RPort,RasterPtr,RightMargin);
  1437.             }
  1438.  
  1439.             if(CursorXSave >= RightMargin)
  1440.                 CursorX = RightMargin - 1;
  1441.             else
  1442.                 CursorX = CursorXSave;
  1443.         }
  1444.  
  1445.         RepositionCursor();
  1446.     }
  1447. }
  1448.  
  1449.     /* AlignmentTest():
  1450.      *
  1451.      *    Perform screen alignment test, fill the screen with `E's.
  1452.      */
  1453.  
  1454. VOID
  1455. AlignmentTest()
  1456. {
  1457.     STRPTR Buffer;
  1458.  
  1459.     if(Buffer = AllocVecPooled(LastColumn + 1,MEMF_ANY))
  1460.     {
  1461.         WORD i;
  1462.  
  1463.         memset(Buffer,'E',LastColumn + 1);
  1464.  
  1465.         EraseScreen("2");
  1466.  
  1467.         if(FontScalingRequired)
  1468.         {
  1469.             for(i = 0 ; i <= LastLine ; i++)
  1470.             {
  1471.                 CursorX = 0;
  1472.                 CursorY = i;
  1473.  
  1474.                 RasterAttr[i] = SCALE_ATTR_NORMAL;
  1475.  
  1476.                 RasterPutString(Buffer,LastColumn + 1);
  1477.                 ScrollLinePutString(LastColumn + 1);
  1478.  
  1479.                 Move(RPort,WindowLeft,WindowTop + MUL_Y(i) + TextFontBase);
  1480.                 PrintScaled(Buffer,LastColumn + 1,SCALE_ATTR_NORMAL);
  1481.             }
  1482.         }
  1483.         else
  1484.         {
  1485.             for(i = 0 ; i <= LastLine ; i++)
  1486.             {
  1487.                 CursorX = 0;
  1488.                 CursorY = i;
  1489.  
  1490.                 RasterPutString(Buffer,LastColumn + 1);
  1491.                 ScrollLinePutString(LastColumn + 1);
  1492.  
  1493.                 Move(RPort,WindowLeft,WindowTop + MUL_Y(i) + TextFontBase);
  1494.                 Text(RPort,Buffer,LastColumn + 1);
  1495.             }
  1496.         }
  1497.  
  1498.         CursorX = CursorY = 0;
  1499.  
  1500.         RethinkRasterLimit();
  1501.  
  1502.         RepositionCursor();
  1503.  
  1504.         FreeVecPooled(Buffer);
  1505.  
  1506.         ConFontScaleUpdate();
  1507.     }
  1508. }
  1509.  
  1510.     /* SetTab():
  1511.      *
  1512.      *    Set a tabulator stop at the current position.
  1513.      */
  1514.  
  1515. VOID
  1516. SetTab()
  1517. {
  1518.     if(CursorX < TabStopMax)
  1519.         TabStops[CursorX] = TRUE;
  1520. }
  1521.  
  1522.     /* RequestTerminal(STRPTR Buffer):
  1523.      *
  1524.      *    Return the current terminal position.
  1525.      */
  1526.  
  1527. VOID
  1528. RequestTerminal(STRPTR Buffer)
  1529. {
  1530.     STRPTR String = NULL;
  1531.  
  1532.     DB(kprintf("|%s|\n",Buffer));
  1533.  
  1534.     switch(Buffer[0])
  1535.     {
  1536.             /* Make ourselves known as a VT200
  1537.              * terminal.
  1538.              */
  1539.  
  1540.         case '[':
  1541.  
  1542.             if(Buffer[1] != '>')
  1543.             {
  1544.                 switch(Config -> EmulationConfig -> TerminalType)
  1545.                 {
  1546.                     case TERMINAL_VT100:
  1547.  
  1548.                         String = "\033[?1;2c";
  1549.                         break;
  1550.  
  1551.                     case TERMINAL_VT101:
  1552.  
  1553.                         String = "\033[?1;0c";
  1554.                         break;
  1555.  
  1556.                     case TERMINAL_VT102:
  1557.  
  1558.                         String = "\033[?6c";
  1559.                         break;
  1560.  
  1561.                     case TERMINAL_VT200:
  1562.  
  1563.                         String = "\233?62;1;2;6;7;8;9c";
  1564.                         break;
  1565.                 }
  1566.             }
  1567.             else
  1568.                 String = "\233>1;10;0c";    // Let's hope this command will never get called when responding in VT10x mode
  1569.  
  1570.             break;
  1571.  
  1572.             /* This is an old VT52 status request type,
  1573.              * we will identify ourselves as a VT100
  1574.              * terminal
  1575.              */
  1576.  
  1577.         case 'Z':
  1578.  
  1579.             switch(Config -> EmulationConfig -> TerminalType)
  1580.             {
  1581.                 case TERMINAL_VT100:
  1582.  
  1583.                     String = "\033/Z";
  1584.                     break;
  1585.  
  1586.                 case TERMINAL_VT101:
  1587.  
  1588.                     String = "\033[?1;0c";
  1589.                     break;
  1590.  
  1591.                 case TERMINAL_VT102:
  1592.  
  1593.                     String = "\033[?6c";
  1594.                     break;
  1595.  
  1596.                 case TERMINAL_VT200:
  1597.  
  1598.                     String = "\233?62;1;2;6;7;8;9c";
  1599.                     break;
  1600.             }
  1601.  
  1602.             break;
  1603.     }
  1604.  
  1605.     DB(kprintf("out |%s|\n",String ? String+1 : "«NULL»"));
  1606.  
  1607.     if(String)
  1608.         EmulationSerWrite(String,-1);
  1609. }
  1610.  
  1611.     /* SoftReset():
  1612.      *
  1613.      *    Plain and simple: reset the text rendering colours, style and the
  1614.      *    font being used. This works similar to the Reset() call which
  1615.      *    also clears the screen.
  1616.      */
  1617.  
  1618. VOID
  1619. SoftReset()
  1620. {
  1621.     ObtainSemaphore(&TerminalSemaphore);
  1622.  
  1623.         /* Are we running on an external emulation? */
  1624.  
  1625.     if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  1626.     {
  1627.         XEmulatorResetTextStyles(XEM_IO);
  1628.         XEmulatorResetCharset(XEM_IO);
  1629.     }
  1630.     else
  1631.     {
  1632.         if(!Config -> EmulationConfig -> FontLocked)
  1633.             CurrentCharWidth = SCALE_NORMAL;
  1634.  
  1635.             /* Reset the text rendering colours. */
  1636.  
  1637.         if(!Config -> EmulationConfig -> LockColour)
  1638.         {
  1639.             if(Config -> ScreenConfig -> ColourMode == COLOUR_SIXTEEN)    // Special case
  1640.                 ForegroundPen = 7;
  1641.             else
  1642.                 ForegroundPen = GetPenIndex(SafeTextPen);
  1643.  
  1644.             BackgroundPen = 0;
  1645.         }
  1646.  
  1647.         if(StyleType != FS_NORMAL && !Config -> EmulationConfig -> LockStyle)
  1648.             StyleType = FS_NORMAL;
  1649.  
  1650.         ConFontScaleUpdate();
  1651.  
  1652.         UpdatePens();
  1653.  
  1654.         SetMask(RPort,DepthMask);
  1655.  
  1656.         CurrentFont = TextFont;
  1657.  
  1658.         SetFont(RPort,CurrentFont);
  1659.  
  1660.         ConOutputUpdate();
  1661.  
  1662.         CursorBackupValid = FALSE;
  1663.  
  1664.         VT52_Mode = FALSE;
  1665.     }
  1666.  
  1667.     ReleaseSemaphore(&TerminalSemaphore);
  1668. }
  1669.  
  1670.     /* Reset():
  1671.      *
  1672.      *    Reset terminal to initial state.
  1673.      */
  1674.  
  1675. VOID
  1676. Reset()
  1677. {
  1678.     LONG    MaxColumns,MaxLines,
  1679.         Columns,Lines,
  1680.         i;
  1681.  
  1682.     ObtainSemaphore(&TerminalSemaphore);
  1683.  
  1684.     CursorEnabled = CursorInvisible = FALSE;
  1685.  
  1686.     if(Window -> Flags & WFLG_WINDOWACTIVE)
  1687.         CursorGhosted = FALSE;
  1688.     else
  1689.         CursorGhosted = TRUE;
  1690.  
  1691.         /* Determine window inner dimensions and top/left edge offsets. */
  1692.  
  1693.     UpdateTerminalLimits();
  1694.  
  1695.     MaxColumns    = WindowWidth / TextFontWidth;
  1696.     MaxLines    = WindowHeight / TextFontHeight;
  1697.  
  1698.         /* Set up the new screen width. */
  1699.  
  1700.     if(Config -> TerminalConfig -> NumColumns < 20)
  1701.         Columns = MaxColumns;
  1702.     else
  1703.         Columns = Config -> TerminalConfig -> NumColumns;
  1704.  
  1705.         /* Set up the new screen height. */
  1706.  
  1707.     if(Config -> TerminalConfig -> NumLines < 20)
  1708.         Lines = MaxLines;
  1709.     else
  1710.         Lines = Config -> TerminalConfig -> NumLines;
  1711.  
  1712.         /* More columns than we will be able to display? */
  1713.  
  1714.     if(Columns > MaxColumns)
  1715.         Columns = MaxColumns;
  1716.  
  1717.         /* More lines than we will be able to display? */
  1718.  
  1719.     if(Lines > MaxLines)
  1720.         Lines = MaxLines;
  1721.  
  1722.         /* Set up the central data. */
  1723.  
  1724.     LastColumn    = Columns - 1;
  1725.     LastLine    = Lines - 1;
  1726.     LastPixel    = MUL_X(Columns) - 1;
  1727.  
  1728.     for(i = 0 ; i <= LastLine ; i++)
  1729.         RasterAttr[i] = SCALE_ATTR_NORMAL;
  1730.  
  1731.     memset(TabStops,FALSE,TabStopMax);
  1732.  
  1733.     for(i = 8 ; i < TabStopMax ; i += 8)
  1734.         TabStops[i] = TRUE;
  1735.  
  1736.     CharMode[0] = TABLE_ASCII;
  1737.     CharMode[1] = TABLE_GFX;
  1738.  
  1739.     Charset = 0;
  1740.  
  1741.     SetAPen(RPort,MappedPens[0][PenTable[0]]);
  1742.  
  1743.     SetMask(RPort,DepthMask);
  1744.  
  1745.     RectFill(RPort,WindowLeft,WindowTop,WindowLeft + WindowWidth - 1,WindowTop + WindowHeight - 1);
  1746.  
  1747.     ScrollLineEraseScreen(2);
  1748.  
  1749.     RasterEraseScreen(2);
  1750.  
  1751.     if(!Config -> EmulationConfig -> LockColour)
  1752.     {
  1753.         if(Config -> ScreenConfig -> ColourMode == COLOUR_SIXTEEN)    // Special case
  1754.             ForegroundPen = 7;
  1755.         else
  1756.             ForegroundPen = GetPenIndex(SafeTextPen);
  1757.  
  1758.         BackgroundPen = 0;
  1759.     }
  1760.  
  1761.     if(StyleType != FS_NORMAL && !Config -> EmulationConfig -> LockStyle)
  1762.         StyleType = FS_NORMAL;
  1763.  
  1764.     UpdatePens();
  1765.  
  1766.     CurrentFont = TextFont;
  1767.  
  1768.     SetFont(RPort,CurrentFont);
  1769.  
  1770.     ConOutputUpdate();
  1771.  
  1772.     UseRegion = FALSE;
  1773.     RegionSet = FALSE;
  1774.  
  1775.     DB(kprintf("scroll region turned off\n"));
  1776.  
  1777.     if(!Config -> EmulationConfig -> CursorLocked)
  1778.         Config -> EmulationConfig -> CursorMode = KEYMODE_STANDARD;
  1779.  
  1780.     if(!Config -> EmulationConfig -> KeysLocked)
  1781.         Config -> EmulationConfig -> NumericMode = KEYMODE_STANDARD;
  1782.  
  1783.     Config -> EmulationConfig -> NewLineMode    = FALSE;
  1784.     Config -> EmulationConfig -> InsertMode        = FALSE;
  1785.     Config -> EmulationConfig -> ScrollMode        = SCROLL_JUMP;
  1786.  
  1787.     if(!Config -> EmulationConfig -> LockWrapping)
  1788.         Config -> EmulationConfig -> LineWrap = TRUE;
  1789.  
  1790.     if(!Config -> EmulationConfig -> FontLocked)
  1791.         CurrentCharWidth = SCALE_NORMAL;
  1792.  
  1793.     if(!Config -> EmulationConfig -> LockStyle)
  1794.         Attributes = 0;
  1795.  
  1796.     VT52_Mode = FALSE;
  1797.  
  1798.     Top        = 0;
  1799.     Bottom        = LastLine;
  1800.     CursorX        = 0;
  1801.     CursorY        = 0;
  1802.  
  1803.     CursorBackup . Charset        = Charset;
  1804.     CursorBackup . Attributes    = Attributes;
  1805.     CursorBackup . CursorX        = CursorX;
  1806.     CursorBackup . CursorY        = CursorY;
  1807.     CursorBackup . Style        = StyleType;
  1808.     CursorBackup . FgPen        = ForegroundPen;
  1809.     CursorBackup . BgPen        = BackgroundPen;
  1810.     CursorBackup . CurrentFont    = CurrentFont;
  1811.     CursorBackup . CharMode[0]    = CharMode[0];
  1812.     CursorBackup . CharMode[1]    = CharMode[1];
  1813.  
  1814.     CursorBackupValid = FALSE;
  1815.  
  1816.     ConFontScaleUpdate();
  1817.  
  1818.     RepositionCursor();
  1819.  
  1820.     ReleaseSemaphore(&TerminalSemaphore);
  1821. }
  1822.  
  1823.     /* PrinterController(STRPTR Buffer):
  1824.      *
  1825.      *    Controls various screen dump and capture functions.
  1826.      */
  1827.  
  1828. VOID
  1829. PrinterController(STRPTR Buffer)
  1830. {
  1831.     if(Config -> EmulationConfig -> PrinterEnabled)
  1832.     {
  1833.         switch(Buffer[1])
  1834.         {
  1835.             case 'i':    // Print screen
  1836.             case '0':
  1837.  
  1838.                 if(PrintFullScreen)
  1839.                     PrintRegion(0,LastLine + 1,PrintFormFeed);
  1840.                 else
  1841.                     PrintRegion(Top,Bottom + 1,PrintFormFeed);
  1842.  
  1843.                 break;
  1844.  
  1845.             case '5':    // Turn on printer controller mode
  1846.  
  1847.                 OpenPrinterCapture(TRUE);
  1848.                 break;
  1849.  
  1850.             case '4':    // Turn off printer controller mode
  1851.  
  1852.                 ClosePrinterCapture(FALSE);
  1853.                 break;
  1854.  
  1855.             case '?':
  1856.  
  1857.                 if(Buffer[2] == '1')    // Print current line
  1858.                     PrintRegion(CursorY,CursorY + 1,FALSE);
  1859.  
  1860.                 if(Buffer[2] == '5')    // Turn on auto print mode
  1861.                     OpenPrinterCapture(FALSE);
  1862.  
  1863.                 if(Buffer[2] == '4')    // Turn off auto print mode
  1864.                     ClosePrinterCapture(FALSE);
  1865.  
  1866.                 break;
  1867.         }
  1868.     }
  1869. }
  1870.  
  1871.     /* RequestInformation(STRPTR Buffer):
  1872.      *
  1873.      *    Request miscellaneous information (state & cursor position).
  1874.      */
  1875.  
  1876. VOID
  1877. RequestInformation(STRPTR Buffer)
  1878. {
  1879.     UBYTE    LocalBuffer[40];
  1880.     WORD    Value;
  1881.  
  1882.     ReadValue(Buffer,&Value);
  1883.  
  1884.     switch(Value)
  1885.     {
  1886.             /* Terminal status report, return code
  1887.              * for `no malfunction'.
  1888.              */
  1889.  
  1890.         case 5:
  1891.  
  1892.             EmulationSerWrite("\033[0n",-1);
  1893.             break;
  1894.  
  1895.             /* The origin is placed at 0/0 and the first
  1896.              * cursor position is 1/1. We'll have to add
  1897.              * 1 to our internal positions since our
  1898.              * universe has been shifted one field to the
  1899.              * left top corner.
  1900.              */
  1901.  
  1902.         case 6:
  1903.  
  1904.             SPrintf(LocalBuffer,"\033[%ld;%ldR",CursorY + 1,CursorX + 1);
  1905.  
  1906.             EmulationSerWrite(LocalBuffer,-1);
  1907.  
  1908.             break;
  1909.  
  1910.             /* A VT200 command: request printer status.
  1911.              * We will return `the printer is ready' in
  1912.              * case the printer control commands are
  1913.              * enabled, else return `no printer connected'.
  1914.              */
  1915.  
  1916.         case 15:
  1917.  
  1918.             if(Config -> EmulationConfig -> PrinterEnabled)
  1919.                 EmulationSerWrite("\033[?10n",-1);
  1920.             else
  1921.                 EmulationSerWrite("\033[?11n",-1);
  1922.  
  1923.             break;
  1924.  
  1925.             /* VT200 command: request user defined
  1926.              * key status. We will return `user
  1927.              * defined keys are locked'.
  1928.              */
  1929.  
  1930.         case 25:
  1931.  
  1932.             EmulationSerWrite("\033[?21n",-1);
  1933.             break;
  1934.  
  1935.             /* Another VT200 command: request
  1936.              * keyboard language. We will return
  1937.              * `keyboard language unknown'.
  1938.              */
  1939.  
  1940.         case 26:
  1941.  
  1942.             EmulationSerWrite("\033[?27;0n",-1);
  1943.             break;
  1944.     }
  1945. }
  1946.  
  1947.     /* SetSomething(STRPTR Buffer):
  1948.      *
  1949.      *    Set a terminal option.
  1950.      */
  1951.  
  1952. VOID
  1953. SetSomething(STRPTR Buffer)
  1954. {
  1955.     WORD    Value;
  1956.     UBYTE    Last;
  1957.     BOOLEAN    TurnOn;
  1958.  
  1959.     ReadValue(Buffer,&Value);
  1960.     Last = LastChar(Buffer);
  1961.  
  1962.     if(Buffer[1] == '?')
  1963.     {
  1964.         switch(Value)
  1965.         {
  1966.                 /* Set cursor keys applications mode. */
  1967.  
  1968.             case 1:        // DECCKM
  1969.  
  1970.                 if(!Config -> EmulationConfig -> CursorLocked)
  1971.                 {
  1972.                     if(Last == 'h')
  1973.                         Config -> EmulationConfig -> CursorMode = KEYMODE_APPLICATION;
  1974.  
  1975.                     if(Last == 'l')
  1976.                         Config -> EmulationConfig -> CursorMode = KEYMODE_STANDARD;
  1977.                 }
  1978.  
  1979.                 break;
  1980.  
  1981.                 /* ANSI/VT52 mode */
  1982.  
  1983.             case 2:        // DECANM
  1984.  
  1985.                 if(Last != 'h')
  1986.                     VT52_Mode = TRUE;
  1987.  
  1988.                 break;
  1989.  
  1990.                 /* Set line length (132 or 80). */
  1991.  
  1992.             case 3:        // DECCOLM
  1993.  
  1994.                 if(!Config -> EmulationConfig -> FontLocked)
  1995.                 {
  1996.                     if(CursorEnabled)
  1997.                     {
  1998.                         ClearCursor();
  1999.  
  2000.                         TurnOn = TRUE;
  2001.                     }
  2002.                     else
  2003.                         TurnOn = FALSE;
  2004.  
  2005.                     if(Last == 'h')
  2006.                     {
  2007.                         if(CurrentCharWidth != SCALE_HALF)
  2008.                         {
  2009.                             CursorX = CursorY = 0;
  2010.  
  2011.                             RepositionCursor();
  2012.  
  2013.                             BackupRender();
  2014.  
  2015.                             SetAPen(RPort,MappedPens[0][PenTable[0]]);
  2016.  
  2017.                             ScrollLineRectFillNoTabChange(RPort,0,0,LastPixel,MUL_Y(LastLine + 1) - 1);
  2018.  
  2019.                             ScrollLineEraseScreen(2);
  2020.  
  2021.                             RasterEraseScreen(2);
  2022.  
  2023.                             SaveConfig(Config,PrivateConfig);
  2024.  
  2025.                             CurrentCharWidth = SCALE_HALF;
  2026.  
  2027.                             BackupRender();
  2028.  
  2029.                             ScreenSizeStuff();
  2030.                         }
  2031.                     }
  2032.  
  2033.                     if(Last == 'l')
  2034.                     {
  2035.                         if(CurrentCharWidth != SCALE_NORMAL)
  2036.                         {
  2037.                             CursorX = CursorY = 0;
  2038.  
  2039.                             RepositionCursor();
  2040.  
  2041.                             BackupRender();
  2042.  
  2043.                             SetAPen(RPort,MappedPens[0][PenTable[0]]);
  2044.  
  2045.                             ScrollLineRectFillNoTabChange(RPort,0,0,LastPixel,MUL_Y(LastLine + 1) - 1);
  2046.  
  2047.                             ScrollLineEraseScreen(2);
  2048.  
  2049.                             RasterEraseScreen(2);
  2050.  
  2051.                             SaveConfig(Config,PrivateConfig);
  2052.  
  2053.                             CurrentCharWidth = SCALE_NORMAL;
  2054.  
  2055.                             BackupRender();
  2056.  
  2057.                             ScreenSizeStuff();
  2058.                         }
  2059.                     }
  2060.  
  2061.                     if(TurnOn)
  2062.                         DrawCursor();
  2063.                     else
  2064.                         ClearCursor();
  2065.                 }
  2066.  
  2067.                 break;
  2068.  
  2069.                 /* Set scroll mode (jump or smooth). */
  2070.  
  2071.             case 4:        // DECSCLM
  2072.  
  2073.                 if(Last == 'h')
  2074.                     Config -> EmulationConfig -> ScrollMode = SCROLL_SMOOTH;
  2075.  
  2076.                 if(Last == 'l')
  2077.                     Config -> EmulationConfig -> ScrollMode = SCROLL_JUMP;
  2078.  
  2079.                 break;
  2080.  
  2081.                 /* Reverse/normal screen. */
  2082.  
  2083.             case 5:        // DECSCNM
  2084.  
  2085.                 break;
  2086.  
  2087.                 /* Turn region on or off. */
  2088.  
  2089.             case 6:
  2090.  
  2091.                 if(Last == 'h')
  2092.                     UseRegion = TRUE;
  2093.  
  2094.                 if(Last == 'l')
  2095.                     UseRegion = FALSE;
  2096.  
  2097.                 DB(kprintf("scroll region = %ld\n",UseRegion));
  2098.  
  2099.                 break;
  2100.  
  2101.                 /* Turn character wrapping on or off. */
  2102.  
  2103.             case 7:        // DECAWM
  2104.  
  2105.                 if(!Config -> EmulationConfig -> LockWrapping)
  2106.                 {
  2107.                     if(Last == 'h')
  2108.                         Config -> EmulationConfig -> LineWrap = TRUE;
  2109.  
  2110.                     if(Last == 'l')
  2111.                         Config -> EmulationConfig -> LineWrap = FALSE;
  2112.                 }
  2113.  
  2114.                 break;
  2115.  
  2116.                 /* Turn auto repeat on or off. */
  2117.  
  2118.             case 8:        // DECARM
  2119.  
  2120.                 break;
  2121.  
  2122.                 /* Set 240/480 line mode. */
  2123.  
  2124.             case 9:
  2125.  
  2126.                 break;
  2127.  
  2128.                 /* Print form feed after `print screen command'. */
  2129.  
  2130.             case 18:    // DECPFF
  2131.  
  2132.                 if(Last == 'h')
  2133.                     PrintFormFeed = TRUE;
  2134.  
  2135.                 if(Last == 'l')
  2136.                     PrintFormFeed = FALSE;
  2137.  
  2138.                 break;
  2139.  
  2140.                 /* Print full screen or just region. */
  2141.  
  2142.             case 19:    // DECPEX
  2143.  
  2144.                 if(Last == 'h')
  2145.                     PrintFullScreen = TRUE;
  2146.  
  2147.                 if(Last == 'l')
  2148.                     PrintFullScreen = FALSE;
  2149.  
  2150.                 break;
  2151.  
  2152.                 /* Text cursor enable. */
  2153.  
  2154.             case 25:    // DECTCEM
  2155.  
  2156.                 TurnOn = CursorEnabled;
  2157.  
  2158.                 ClearCursor();
  2159.  
  2160.                 if(Last == 'h')
  2161.                     CursorInvisible = FALSE;
  2162.  
  2163.                 if(Last == 'l')
  2164.                     CursorInvisible = TRUE;
  2165.  
  2166.                 if(TurnOn)
  2167.                     DrawCursor();
  2168.  
  2169.                 break;
  2170.  
  2171.                 /* National/multinational character set. */
  2172.  
  2173.             case 42:    // DECNRCM
  2174.  
  2175.                 break;
  2176.         }
  2177.     }
  2178.     else
  2179.     {
  2180.         switch(Value)
  2181.         {
  2182.                 /* Keyboard action unlocked/locked. */
  2183.  
  2184.             case 2:        // KAM
  2185.  
  2186.                 break;
  2187.  
  2188.                 /* Insertion/replacement. */
  2189.  
  2190.             case 4:        // IRM
  2191.  
  2192.                 if(Last == 'h')
  2193.                     Config -> EmulationConfig -> InsertMode = TRUE;
  2194.  
  2195.                 if(Last == 'l')
  2196.                     Config -> EmulationConfig -> InsertMode = FALSE;
  2197.  
  2198.                 break;
  2199.  
  2200.                 /* Echo on/off. */
  2201.  
  2202.             case 12:    // SRM
  2203.  
  2204.                 if(Last == 'h')
  2205.                     Config -> SerialConfig -> Duplex = DUPLEX_FULL;
  2206.  
  2207.                 if(Last == 'l')
  2208.                     Config -> SerialConfig -> Duplex = DUPLEX_HALF;
  2209.  
  2210.                 break;
  2211.  
  2212.                 /* Line feed/new line. */
  2213.  
  2214.             case 20:    // LNM
  2215.  
  2216.                 if(Last == 'h')
  2217.                     Config -> EmulationConfig -> NewLineMode = TRUE;
  2218.  
  2219.                 if(Last == 'l')
  2220.                     Config -> EmulationConfig -> NewLineMode = FALSE;
  2221.  
  2222.                 break;
  2223.         }
  2224.     }
  2225. }
  2226.  
  2227.     /* NumericAppMode(STRPTR Buffer):
  2228.      *
  2229.      *    Set the numeric pad applications mode.
  2230.      */
  2231.  
  2232. VOID
  2233. NumericAppMode(STRPTR Buffer)
  2234. {
  2235.     if(!Config -> EmulationConfig -> KeysLocked)
  2236.     {
  2237.         if(*Buffer == '=')
  2238.             Config -> EmulationConfig -> NumericMode = KEYMODE_APPLICATION;
  2239.         else
  2240.         {
  2241.             if(*Buffer == '>')
  2242.                 Config -> EmulationConfig -> NumericMode = KEYMODE_STANDARD;
  2243.         }
  2244.     }
  2245. }
  2246.  
  2247.     /* MoveCursor(STRPTR Buffer):
  2248.      *
  2249.      *    Move the cursor in some direction and stop at
  2250.      *    top/bottom/margin if necessary.
  2251.      */
  2252.  
  2253. VOID
  2254. MoveCursor(STRPTR Buffer)
  2255. {
  2256.     WORD Value,Hit;
  2257.     BYTE InRegion = TRUE;
  2258.  
  2259.     ReadValue(Buffer,&Value);
  2260.  
  2261.     if(Value < 1)
  2262.         Value = 1;
  2263.  
  2264.     switch(LastChar(Buffer))
  2265.     {
  2266.             /* Move cursor Up value lines */
  2267.  
  2268.         case 'A':
  2269.  
  2270. ScrollUp:        Hit = 0;
  2271.  
  2272.             if(RegionSet)
  2273.             {
  2274.                 if(CursorY >= Top)
  2275.                     Hit = Top;
  2276.                 else
  2277.                     InRegion = FALSE;
  2278.             }
  2279.  
  2280.             CursorY -= Value;
  2281.  
  2282.             if(CursorY < Hit)
  2283.             {
  2284.                 Value = CursorY - Hit;
  2285.  
  2286.                 CursorY = Hit;
  2287.  
  2288.                 if(Config -> EmulationConfig -> CursorWrap && InRegion)
  2289.                     ScrollRegion(Value);
  2290.             }
  2291.  
  2292.             ConFontScaleUpdate();
  2293.  
  2294.             break;
  2295.  
  2296.             /* Move cursor Down value lines */
  2297.  
  2298.         case 'B':
  2299.  
  2300. ScrollDown:        Hit = LastLine;
  2301.  
  2302.             if(RegionSet)
  2303.             {
  2304.                 if(CursorY <= Bottom)
  2305.                     Hit = Bottom;
  2306.                 else
  2307.                     InRegion = FALSE;
  2308.             }
  2309.  
  2310.             CursorY += Value;
  2311.  
  2312.             if(CursorY > Hit)
  2313.             {
  2314.                 Value = CursorY - Hit;
  2315.  
  2316.                 CursorY = Hit;
  2317.  
  2318.                 if(Config -> EmulationConfig -> CursorWrap && InRegion)
  2319.                     ScrollRegion(Value);
  2320.             }
  2321.  
  2322.             ConFontScaleUpdate();
  2323.  
  2324.             break;
  2325.  
  2326.             /* Move cursor Right value columns */
  2327.  
  2328.         case 'C':
  2329.  
  2330.             CursorX += Value;
  2331.  
  2332.             if(CursorX > LastPrintableColumn)
  2333.             {
  2334.                 if(Config -> EmulationConfig -> CursorWrap)
  2335.                 {
  2336.                     Value = CursorX / (LastPrintableColumn + 1);
  2337.  
  2338.                     CursorX    -= Value * (LastPrintableColumn + 1);
  2339.  
  2340.                     goto ScrollDown;
  2341.                 }
  2342.                 else
  2343.                     CursorX = LastPrintableColumn;
  2344.             }
  2345.  
  2346.             break;
  2347.  
  2348.             /* Move cursor Left value columns */
  2349.  
  2350.         case 'D':
  2351.  
  2352.             CursorX -= Value;
  2353.  
  2354.             if(CursorX < 0)
  2355.             {
  2356.                 if(Config -> EmulationConfig -> CursorWrap)
  2357.                 {
  2358.                     Value     = CursorX / (LastPrintableColumn + 1);
  2359.                     CursorX    -= Value * (LastPrintableColumn + 1);
  2360.                     Value     = -Value;
  2361.  
  2362.                     goto ScrollDown;
  2363.                 }
  2364.                 else
  2365.                     CursorX = 0;
  2366.             }
  2367.  
  2368.             break;
  2369.     }
  2370.  
  2371.     if(CursorX > LastPrintableColumn)
  2372.         CursorX = LastPrintableColumn;
  2373.  
  2374.     RepositionCursor();
  2375. }
  2376.  
  2377.     /* MoveColumn(STRPTR Buffer):
  2378.      *
  2379.      *    Move the cursor to a certain column.
  2380.      */
  2381.  
  2382. VOID
  2383. MoveColumn(STRPTR Buffer)
  2384. {
  2385.     WORD Value;
  2386.  
  2387.     ReadValue(Buffer,&Value);
  2388.  
  2389.     if(Value < 1)
  2390.         Value = 1;
  2391.  
  2392.     CursorX = Value - 1;
  2393.  
  2394.     if(CursorX < 0)
  2395.         CursorX = 0;
  2396.  
  2397.     if(CursorX > LastPrintableColumn)
  2398.         CursorX = LastPrintableColumn;
  2399.  
  2400.     RepositionCursor();
  2401. }
  2402.  
  2403.     /* EraseLine(STRPTR Buffer):
  2404.      *
  2405.      *    Erase a line on the display.
  2406.      */
  2407.  
  2408. VOID
  2409. EraseLine(STRPTR Buffer)
  2410. {
  2411.     WORD Value,Width = GetFontWidth();
  2412.  
  2413.     if(*Buffer == '?')
  2414.         Buffer++;
  2415.  
  2416.     ReadValue(Buffer,&Value);
  2417.  
  2418.     BackupRender();
  2419.  
  2420.     switch(Value)
  2421.     {
  2422.         case 1:
  2423.  
  2424.             if(CursorX)
  2425.                 ScrollLineRectFillNoTabChange(RPort,0,MUL_Y(CursorY),CursorX * Width - 1,MUL_Y(CursorY + 1) - 1);
  2426.  
  2427.             break;
  2428.  
  2429.         case 2:
  2430.  
  2431.             ScrollLineRectFillNoTabChange(RPort,0,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1);
  2432.             break;
  2433.  
  2434.         default:
  2435.  
  2436.             ScrollLineRectFillNoTabChange(RPort,CursorX * Width,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1);
  2437.             break;
  2438.     }
  2439.  
  2440.     ScrollLineEraseLine(Value);
  2441.  
  2442.     RasterEraseLine(Value);
  2443.  
  2444.     BackupRender();
  2445. }
  2446.  
  2447.     /* EraseScreen(STRPTR Buffer):
  2448.      *
  2449.      *    Erase parts of the screen.
  2450.      */
  2451.  
  2452. VOID
  2453. EraseScreen(STRPTR Buffer)
  2454. {
  2455.     WORD Value,Width = GetFontWidth();
  2456.  
  2457.     if(*Buffer == '?')
  2458.         Buffer++;
  2459.  
  2460.     ReadValue(Buffer,&Value);
  2461.  
  2462.     BackupRender();
  2463.  
  2464.     switch(Value)
  2465.     {
  2466.         case 1:
  2467.  
  2468.             if(CursorY)
  2469.                 ScrollLineRectFillNoTabChange(RPort,0,0,LastPixel,MUL_Y(CursorY) - 1);
  2470.  
  2471.             if(CursorX)
  2472.                 ScrollLineRectFillNoTabChange(RPort,0,MUL_Y(CursorY),CursorX * Width - 1,MUL_Y(CursorY + 1) - 1);
  2473.  
  2474.             break;
  2475.  
  2476.         case 2:
  2477.  
  2478.             ScrollLineRectFillNoTabChange(RPort,0,0,LastPixel,MUL_Y(LastLine + 1) - 1);
  2479.  
  2480.             if(Config -> EmulationConfig -> CLSResetsCursor)
  2481.                 CursorX = CursorY = 0;
  2482.  
  2483.             break;
  2484.  
  2485.         default:
  2486.  
  2487.             ScrollLineRectFillNoTabChange(RPort,CursorX * Width,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1);
  2488.  
  2489.             if(CursorY != LastLine)
  2490.                 ScrollLineRectFillNoTabChange(RPort,0,MUL_Y(CursorY + 1),LastPixel,MUL_Y(LastLine + 1) - 1);
  2491.  
  2492.             break;
  2493.     }
  2494.  
  2495.     ScrollLineEraseScreen(Value);
  2496.  
  2497.     RasterEraseScreen(Value);
  2498.  
  2499.     BackupRender();
  2500. }
  2501.  
  2502.     /* EraseCharacters(STRPTR Buffer):
  2503.      *
  2504.      *    Erase a number of characters.
  2505.      */
  2506.  
  2507. VOID
  2508. EraseCharacters(STRPTR Buffer)
  2509. {
  2510.     WORD Value,Width = GetFontWidth();
  2511.  
  2512.     if(*Buffer == '?')
  2513.         Buffer++;
  2514.  
  2515.     ReadValue(Buffer,&Value);
  2516.  
  2517.     BackupRender();
  2518.  
  2519.     if(Value < 1)
  2520.         Value = 1;
  2521.  
  2522.     if(Value > LastPrintableColumn)
  2523.         Value = LastPrintableColumn;
  2524.  
  2525.     RasterEraseCharacters(Value);
  2526.  
  2527.     ScrollLineRasterNoTabChange(RPort,Value * Width,0,CursorX * Width,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1,FALSE);
  2528.  
  2529.     ScrollLineEraseCharacters(Value);
  2530.  
  2531.     BackupRender();
  2532. }
  2533.  
  2534.     /* InsertCharacters(STRPTR Buffer):
  2535.      *
  2536.      *    Insert a number of characters.
  2537.      */
  2538.  
  2539. VOID
  2540. InsertCharacters(STRPTR Buffer)
  2541. {
  2542.     WORD Value,Width = GetFontWidth();
  2543.  
  2544.     ReadValue(Buffer,&Value);
  2545.  
  2546.     BackupRender();
  2547.  
  2548.     if(Value < 1)
  2549.         Value = 1;
  2550.  
  2551.     if(CursorX + Value > LastPrintableColumn)
  2552.         Value = LastPrintableColumn - CursorX;
  2553.  
  2554.     if(Value > 0)
  2555.     {
  2556.         RasterShiftChar(Value);
  2557.  
  2558.         ScrollLineRasterNoTabChange(RPort,-Value * Width,0,CursorX * Width,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1,FALSE);
  2559.  
  2560.         ScrollLineShiftChar(Value);
  2561.     }
  2562.  
  2563.     BackupRender();
  2564. }
  2565.  
  2566.     /* InsertLine(STRPTR Buffer):
  2567.      *
  2568.      *    Insert a number of lines and scroll the rest of the
  2569.      *    display down.
  2570.      */
  2571.  
  2572. VOID
  2573. InsertLine(STRPTR Buffer)
  2574. {
  2575.     WORD Value,RegionBottom,RegionTop,TheTop = CursorY;
  2576.  
  2577.     ReadValue(Buffer,&Value);
  2578.  
  2579.     BackupRender();
  2580.  
  2581.     SetAPen(RPort,MappedPens[0][PenTable[0]]);
  2582.  
  2583.     if(Value < 1)
  2584.         Value = 1;
  2585.  
  2586.     if(RegionSet)
  2587.     {
  2588.         RegionTop    = Top;
  2589.         RegionBottom    = Bottom + 1;
  2590.     }
  2591.     else
  2592.     {
  2593.         RegionTop    = 0;
  2594.         RegionBottom    = LastLine + 1;
  2595.     }
  2596.  
  2597.     if(TheTop < RegionTop)
  2598.         TheTop = RegionTop;
  2599.  
  2600.     if(TheTop + Value > RegionBottom)
  2601.         Value = RegionBottom - TheTop;
  2602.  
  2603.     if(Value > 0)
  2604.     {
  2605.         RasterInsertLine(Value,TheTop);
  2606.  
  2607.         ScrollLineRaster(RPort,0,-MUL_Y(Value),0,MUL_Y(TheTop),LastPixel,MUL_Y(RegionBottom) - 1,FALSE);
  2608.     }
  2609.  
  2610.     BackupRender();
  2611. }
  2612.  
  2613.     /* ClearLine(STRPTR Buffer):
  2614.      *
  2615.      *    Clear a number of lines and scroll up the ones below it.
  2616.      */
  2617.  
  2618. VOID
  2619. ClearLine(STRPTR Buffer)
  2620. {
  2621.     WORD Value,RegionBottom,RegionTop,TheTop = CursorY;
  2622.  
  2623.     ReadValue(Buffer,&Value);
  2624.  
  2625.     BackupRender();
  2626.  
  2627.     SetAPen(RPort,MappedPens[0][PenTable[0]]);
  2628.  
  2629.     if(Value < 1)
  2630.         Value = 1;
  2631.  
  2632.     if(RegionSet)
  2633.     {
  2634.         RegionTop    = Top;
  2635.         RegionBottom    = Bottom + 1;
  2636.     }
  2637.     else
  2638.     {
  2639.         RegionTop    = 0;
  2640.         RegionBottom    = LastLine + 1;
  2641.     }
  2642.  
  2643.     if(TheTop < RegionTop)
  2644.         TheTop = RegionTop;
  2645.  
  2646.     if(TheTop + Value > RegionBottom)
  2647.         Value = RegionBottom - TheTop;
  2648.  
  2649.     if(Value > 0)
  2650.     {
  2651.         RasterClearLine(Value,TheTop);
  2652.  
  2653.         ScrollLineRaster(RPort,0,MUL_Y(Value),0,MUL_Y(TheTop),LastPixel,MUL_Y(RegionBottom) - 1,FALSE);
  2654.     }
  2655.  
  2656.     BackupRender();
  2657. }
  2658.  
  2659.     /* SetTabs(STRPTR Buffer):
  2660.      *
  2661.      *    Set the current tab stops.
  2662.      */
  2663.  
  2664. VOID
  2665. SetTabs(STRPTR Buffer)
  2666. {
  2667.     WORD Value;
  2668.  
  2669.     ReadValue(Buffer,&Value);
  2670.  
  2671.     if(Value < 1)
  2672.         Value = 0;
  2673.  
  2674.     switch(Value)
  2675.     {
  2676.         case 0:
  2677.  
  2678.             if(CursorX < TabStopMax)
  2679.                 TabStops[CursorX] = FALSE;
  2680.  
  2681.             break;
  2682.  
  2683.         case 3:
  2684.  
  2685.             memset(TabStops,FALSE,TabStopMax);
  2686.  
  2687.             break;
  2688.  
  2689.         default:
  2690.  
  2691.             break;
  2692.     }
  2693. }
  2694.  
  2695.     /* SetAbsolutePosition(STRPTR Buffer):
  2696.      *
  2697.      *    Move the cursor to a given location on the display,
  2698.      *    this routine ignores the current scroll region
  2699.      *    settings.
  2700.      */
  2701.  
  2702. VOID
  2703. SetAbsolutePosition(STRPTR Buffer)
  2704. {
  2705.     WORD Value;
  2706.  
  2707.     Buffer = ReadValue(Buffer,&Value);
  2708.  
  2709.     CursorY = 0;
  2710.     CursorX = 0;
  2711.  
  2712.     if(Value == -1)
  2713.         ConFontScaleUpdate();
  2714.     else
  2715.     {
  2716.             /* Our raster origin is 0/0 instead of 1/1. */
  2717.  
  2718.         if(Value)
  2719.             Value--;
  2720.  
  2721.         CursorY = Value;
  2722.  
  2723.         if(Buffer)
  2724.         {
  2725.             ReadValue(Buffer,&Value);
  2726.  
  2727.             if(Value > 0)
  2728.                 CursorX = Value - 1;
  2729.             else
  2730.                 CursorX = 0;
  2731.         }
  2732.  
  2733.             /* Truncate illegal positions. */
  2734.  
  2735.         if(CursorY > LastLine)
  2736.             CursorY = LastLine;
  2737.  
  2738.         ConFontScaleUpdate();
  2739.  
  2740.         if(CursorX > LastPrintableColumn)
  2741.             CursorX = LastPrintableColumn;
  2742.     }
  2743.  
  2744.     RepositionCursor();
  2745. }
  2746.  
  2747.     /* SetTopPosition(STRPTR Buffer):
  2748.      *
  2749.      *    Move the cursor to a given location on the display,
  2750.      *    this routine respects the current scroll region
  2751.      *    settings.
  2752.      */
  2753.  
  2754. VOID
  2755. SetTopPosition(STRPTR Buffer)
  2756. {
  2757.     WORD Value;
  2758.  
  2759.     Buffer = ReadValue(Buffer,&Value);
  2760.  
  2761.     if(UseRegion && RegionSet)
  2762.         CursorY = Top;
  2763.     else
  2764.         CursorY = 0;
  2765.  
  2766.     CursorX = 0;
  2767.  
  2768.     if(Value == -1)
  2769.         ConFontScaleUpdate();
  2770.     else
  2771.     {
  2772.             /* Our raster origin is 0/0 instead of 1/1. */
  2773.  
  2774.         if(Value)
  2775.             Value--;
  2776.  
  2777.         if(UseRegion && RegionSet)
  2778.             CursorY = Top + Value;
  2779.         else
  2780.             CursorY = Value;
  2781.  
  2782.         if(Buffer)
  2783.         {
  2784.             ReadValue(Buffer,&Value);
  2785.  
  2786.             if(Value > 0)
  2787.                 CursorX = Value - 1;
  2788.             else
  2789.                 CursorX = 0;
  2790.         }
  2791.  
  2792.             /* Truncate illegal positions. */
  2793.  
  2794.         if(CursorY > LastLine)
  2795.             CursorY = LastLine;
  2796.  
  2797.         ConFontScaleUpdate();
  2798.  
  2799.         if(CursorX > LastPrintableColumn)
  2800.             CursorX = LastPrintableColumn;
  2801.     }
  2802.  
  2803.     RepositionCursor();
  2804. }
  2805.  
  2806.     /* SetAttributes(STRPTR Buffer):
  2807.      *
  2808.      *    Set the current display rendering attributes.
  2809.      */
  2810.  
  2811. VOID
  2812. SetAttributes(STRPTR Buffer)
  2813. {
  2814.     WORD Value;
  2815.  
  2816.     do
  2817.     {
  2818.         Buffer = ReadValue(Buffer,&Value);
  2819.  
  2820.         if(Value == -1)
  2821.             Value = 0;
  2822.  
  2823.         switch(Value)
  2824.         {
  2825.             case 0:
  2826.  
  2827.                 if(!Config -> EmulationConfig -> LockColour)
  2828.                 {
  2829.                     if(Config -> ScreenConfig -> ColourMode == COLOUR_SIXTEEN)    // Special case
  2830.                         ForegroundPen = 7;
  2831.                     else
  2832.                         ForegroundPen = GetPenIndex(SafeTextPen);
  2833.  
  2834.                     BackgroundPen = 0;
  2835.                 }
  2836.  
  2837.                 if(!Config -> EmulationConfig -> LockStyle)
  2838.                     Attributes = 0;
  2839.  
  2840.                 break;
  2841.  
  2842.             case 1:
  2843.  
  2844.                 if(!Config -> EmulationConfig -> LockStyle)
  2845.                     Attributes |= ATTR_HIGHLIGHT;
  2846.  
  2847.                 break;
  2848.  
  2849.             case 4:
  2850.  
  2851.                 if(!Config -> EmulationConfig -> LockStyle)
  2852.                     Attributes |= ATTR_UNDERLINE;
  2853.  
  2854.                 break;
  2855.  
  2856.             case 5:
  2857.  
  2858.                 if(!Config -> EmulationConfig -> LockStyle)
  2859.                     Attributes |= ATTR_BLINK;
  2860.  
  2861.                 break;
  2862.  
  2863.             case 7:
  2864.  
  2865.                 if(!Config -> EmulationConfig -> LockStyle)
  2866.                     Attributes |= ATTR_INVERSE;
  2867.  
  2868.                 break;
  2869.  
  2870.             case 22:
  2871.  
  2872.                 if(!Config -> EmulationConfig -> LockStyle)
  2873.                     Attributes &= ~ATTR_HIGHLIGHT;
  2874.  
  2875.                 break;
  2876.  
  2877.             case 24:
  2878.  
  2879.                 if(!Config -> EmulationConfig -> LockStyle)
  2880.                     Attributes &= ~ATTR_UNDERLINE;
  2881.  
  2882.                 break;
  2883.  
  2884.             case 25:
  2885.  
  2886.                 if(!Config -> EmulationConfig -> LockStyle)
  2887.                     Attributes &= ~ATTR_BLINK;
  2888.  
  2889.                 break;
  2890.  
  2891.             case 27:
  2892.  
  2893.                 if(!Config -> EmulationConfig -> LockStyle)
  2894.                     Attributes &= ~ATTR_INVERSE;
  2895.  
  2896.                 break;
  2897.  
  2898.             default:
  2899.  
  2900.                 if(!Config -> EmulationConfig -> LockColour)
  2901.                 {
  2902.                     if(Value >= 30)
  2903.                     {
  2904.                         if(Value <= 37)
  2905.                             ForegroundPen = Value - 30;
  2906.                         else
  2907.                         {
  2908.                             if(Value >= 40 && Value <= 47)
  2909.                                 BackgroundPen = Value - 40;
  2910.                         }
  2911.                     }
  2912.                 }
  2913.  
  2914.                 break;
  2915.         }
  2916.     }
  2917.     while(Buffer);
  2918.  
  2919.     UpdatePens();
  2920.  
  2921.     RepositionCursor();
  2922. }
  2923.  
  2924.     /* SetRegion(STRPTR Buffer):
  2925.      *
  2926.      *    Set the current scroll region top and bottom.
  2927.      */
  2928.  
  2929. VOID
  2930. SetRegion(STRPTR Buffer)
  2931. {
  2932.     WORD NewTop,Value,NewBottom = LastLine;
  2933.  
  2934.     Buffer = ReadValue(Buffer,&Value);
  2935.  
  2936.     if(!Value)
  2937.         Value = 1;
  2938.  
  2939.     if(Value > 0)
  2940.     {
  2941.         if(Buffer)
  2942.         {
  2943.             NewTop = Value - 1;
  2944.  
  2945.             ReadValue(Buffer,&Value);
  2946.  
  2947.             if(Value > 0)
  2948.                 NewBottom = Value - 1;
  2949.  
  2950.             if(NewBottom > LastLine)
  2951.                 NewBottom = LastLine;
  2952.  
  2953.             if(NewTop > LastLine)
  2954.                 NewTop = LastLine;
  2955.         }
  2956.         else
  2957.         {
  2958.             NewTop        = 0;
  2959.             NewBottom    = LastLine;
  2960.         }
  2961.     }
  2962.     else
  2963.     {
  2964.         NewTop        = 0;
  2965.         NewBottom    = LastLine;
  2966.     }
  2967.  
  2968.     if(NewTop < NewBottom)
  2969.     {
  2970.         if(NewTop != 0 || NewBottom != LastLine)
  2971.         {
  2972.             Top    = NewTop;
  2973.             Bottom    = NewBottom;
  2974.  
  2975.                 // FIXME: not sure about this one
  2976.  
  2977.             UseRegion = TRUE;
  2978.  
  2979.             RegionSet = TRUE;
  2980.         }
  2981.         else
  2982.             UseRegion = RegionSet = FALSE;
  2983.  
  2984.         DB(kprintf("scroll region %ld -> %ld\n",Top,Bottom));
  2985.  
  2986.         ResetCursor();
  2987.     }
  2988.     else
  2989.         RegionSet = FALSE;
  2990. }
  2991.  
  2992.     /* ResetCursor():
  2993.      *
  2994.      *    Reset cursor to top of screen.
  2995.      */
  2996.  
  2997. VOID
  2998. ResetCursor()
  2999. {
  3000.     CursorX    = 0;
  3001.  
  3002.     if(UseRegion && RegionSet)
  3003.         CursorY = Top;
  3004.     else
  3005.         CursorY    = 0;
  3006.  
  3007.     ConFontScaleUpdate();
  3008.  
  3009.     RepositionCursor();
  3010. }
  3011.  
  3012.     /* MoveCursorUp(STRPTR Buffer):
  3013.      *
  3014.      *    Move the cursor up <n> lines, scroll the screen
  3015.      *    contents if necessary.
  3016.      */
  3017.  
  3018. VOID
  3019. MoveCursorUp(STRPTR Buffer)
  3020. {
  3021.     WORD Value,i;
  3022.  
  3023.     ReadValue(Buffer,&Value);
  3024.  
  3025.     if(Value < 1)
  3026.         Value = 1;
  3027.  
  3028.     for(i = 0 ; i < Value ; i++)
  3029.         CursorScrollUp();
  3030.  
  3031.     CursorX = 0;
  3032.  
  3033.     RepositionCursor();
  3034. }
  3035.  
  3036.     /* MoveCursorDown(STRPTR Buffer):
  3037.      *
  3038.      *    Move the cursor down <n> lines, scroll the screen
  3039.      *    contents if necessary.
  3040.      */
  3041.  
  3042. VOID
  3043. MoveCursorDown(STRPTR Buffer)
  3044. {
  3045.     WORD Value,i;
  3046.  
  3047.     ReadValue(Buffer,&Value);
  3048.  
  3049.     if(Value < 1)
  3050.         Value = 1;
  3051.  
  3052.     for(i = 0 ; i < Value ; i++)
  3053.         DownLine();
  3054.  
  3055.     CursorX = 0;
  3056.  
  3057.     RepositionCursor();
  3058. }
  3059.  
  3060.     /* VT52_CursorUp(STRPTR Buffer):
  3061.      *
  3062.      *    Move the cursor up one line.
  3063.      */
  3064.  
  3065. VOID
  3066. VT52_CursorUp(STRPTR Buffer)
  3067. {
  3068.     if(CursorY > 0)
  3069.     {
  3070.         CursorY--;
  3071.  
  3072.         RepositionCursor();
  3073.     }
  3074. }
  3075.  
  3076.     /* VT52_CursorDown(STRPTR Buffer):
  3077.      *
  3078.      *    Move the cursor down one line.
  3079.      */
  3080.  
  3081. VOID
  3082. VT52_CursorDown(STRPTR Buffer)
  3083. {
  3084.     if(CursorY < LastLine)
  3085.     {
  3086.         CursorY++;
  3087.  
  3088.         RepositionCursor();
  3089.     }
  3090. }
  3091.  
  3092.     /* VT52_CursorRight(STRPTR Buffer):
  3093.      *
  3094.      *    Move the cursor right one column.
  3095.      */
  3096.  
  3097. VOID
  3098. VT52_CursorRight(STRPTR Buffer)
  3099. {
  3100.     if(CursorX < LastColumn)
  3101.     {
  3102.         CursorX++;
  3103.  
  3104.         RepositionCursor();
  3105.     }
  3106. }
  3107.  
  3108.     /* VT52_CursorLeft(STRPTR Buffer):
  3109.      *
  3110.      *    Move the cursor left one column.
  3111.      */
  3112.  
  3113. VOID
  3114. VT52_CursorLeft(STRPTR Buffer)
  3115. {
  3116.         // This command is shared by the VT220 emulation and
  3117.         // the VT52 mode.
  3118.  
  3119.     if(VT52_Mode)
  3120.     {
  3121.         if(CursorX > 0)
  3122.         {
  3123.             CursorX--;
  3124.  
  3125.             RepositionCursor();
  3126.         }
  3127.     }
  3128.     else
  3129.         CursorScrollDown();    // IND
  3130. }
  3131.  
  3132.     /* VT52_CursorHome(STRPTR Buffer):
  3133.      *
  3134.      *    Move the cursor to the home position.
  3135.      */
  3136.  
  3137. VOID
  3138. VT52_CursorHome(STRPTR Buffer)
  3139. {
  3140.         // This command is shared by the VT220 emulation and
  3141.         // the VT52 mode.
  3142.  
  3143.     if(VT52_Mode)
  3144.     {
  3145.         CursorX = CursorY = 0;
  3146.  
  3147.         RepositionCursor();
  3148.     }
  3149.     else
  3150.         SetTab();
  3151. }
  3152.  
  3153.     /* VT52_RevLF(STRPTR Buffer):
  3154.      *
  3155.      *    Perform reverse line feed, i.e. move cursor up one line.
  3156.      */
  3157.  
  3158. VOID
  3159. VT52_RevLF(STRPTR Buffer)
  3160. {
  3161.     if(CursorY > 0)
  3162.     {
  3163.         CursorY--;
  3164.  
  3165.         RepositionCursor();
  3166.     }
  3167. }
  3168.  
  3169.     /* VT52_EraseEOS(STRPTR Buffer):
  3170.      *
  3171.      *    Erase till end of screen.
  3172.      */
  3173.  
  3174. VOID
  3175. VT52_EraseEOS(STRPTR Buffer)
  3176. {
  3177.     EraseScreen("0");
  3178. }
  3179.  
  3180.     /* VT52_EraseEOL(STRPTR Buffer):
  3181.      *
  3182.      *    Erase till end of line.
  3183.      */
  3184.  
  3185. VOID
  3186. VT52_EraseEOL(STRPTR Buffer)
  3187. {
  3188.     EraseLine("0");
  3189. }
  3190.  
  3191.     /* VT52_SetCursor(STRPTR Buffer):
  3192.      *
  3193.      *    Direct cursor address; move the cursor to a
  3194.      *    specific position.
  3195.      */
  3196.  
  3197. VOID
  3198. VT52_SetCursor(STRPTR Buffer)
  3199. {
  3200.     CursorX = Buffer[2] - ' ';
  3201.     CursorY = Buffer[1] - ' ';
  3202.  
  3203.     if(CursorX < 0)
  3204.         CursorX = 0;
  3205.     else
  3206.     {
  3207.         if(CursorX > LastColumn)
  3208.             CursorX = LastColumn;
  3209.     }
  3210.  
  3211.     if(CursorY < 0)
  3212.         CursorY = 0;
  3213.     else
  3214.     {
  3215.         if(CursorY > LastLine)
  3216.             CursorY = LastLine;
  3217.     }
  3218.  
  3219.     RepositionCursor();
  3220. }
  3221.  
  3222.     /* VT52_PrintOn(STRPTR Buffer):
  3223.      *
  3224.      *    Enter printer controller mode.
  3225.      */
  3226.  
  3227. VOID
  3228. VT52_PrintOn(STRPTR Buffer)
  3229. {
  3230.     OpenPrinterCapture(FALSE);
  3231. }
  3232.  
  3233.     /* VT52_PrintOff(STRPTR Buffer):
  3234.      *
  3235.      *    Exit printer controller mode.
  3236.      */
  3237.  
  3238. VOID
  3239. VT52_PrintOff(STRPTR Buffer)
  3240. {
  3241.     ClosePrinterCapture(FALSE);
  3242. }
  3243.  
  3244.     /* VT52_PrintScreen(STRPTR Buffer):
  3245.      *
  3246.      *    Print the entire screen.
  3247.      */
  3248.  
  3249. VOID
  3250. VT52_PrintScreen(STRPTR Buffer)
  3251. {
  3252.     PrintRegion(0,LastLine + 1,PrintFormFeed);
  3253. }
  3254.  
  3255.     /* VT52_PrintLine(STRPTR Buffer):
  3256.      *
  3257.      *    Print the line the cursor sits in.
  3258.      */
  3259.  
  3260. VOID
  3261. VT52_PrintLine(STRPTR Buffer)
  3262. {
  3263.     PrintRegion(CursorY,CursorY + 1,FALSE);
  3264. }
  3265.  
  3266.     /* VT52_EnterANSI(STRPTR Buffer):
  3267.      *
  3268.      *    Return to ANSI mode, or in other terms, change
  3269.      *    the behaviour of the "<ESC>H" and "<ESC>D" commands.
  3270.      */
  3271.  
  3272. VOID
  3273. VT52_EnterANSI(STRPTR Buffer)
  3274. {
  3275.     VT52_Mode = FALSE;
  3276. }
  3277.